package com.fsnbigdata.repository;
import com.fsnbigdata.domain.Ecosystem;
import com.fsnbigdata.domain.QEcosystem;
import com.querydsl.core.types.Predicate;
import io.springlets.data.jpa.repository.support.QueryDslRepositorySupportExt;
import org.springframework.roo.addon.layers.repository.jpa.annotations.RooJpaRepositoryCustomImpl;
import com.fsnbigdata.domain.Document;
import com.fsnbigdata.domain.Organism;
import com.fsnbigdata.domain.QDocument;
import com.fsnbigdata.domain.Specimen;
import com.querydsl.core.types.Path;
import com.querydsl.jpa.JPQLQuery;
import io.springlets.data.domain.GlobalSearch;
import io.springlets.data.jpa.repository.support.QueryDslRepositorySupportExt.AttributeMappingBuilder;
import java.util.List;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

/**
 * = DocumentRepositoryImpl
 *
 * TODO Auto-generated class documentation
 *
 */
@RooJpaRepositoryCustomImpl(repository = DocumentRepositoryCustom.class)
@Transactional(readOnly = true)
public class DocumentRepositoryImpl extends QueryDslRepositorySupportExt<Document> implements DocumentRepositoryCustom {

    /**
     * TODO Auto-generated constructor documentation
     */
    DocumentRepositoryImpl() {
        super(Document.class);
    }

    /**
     * TODO Auto-generated attribute documentation
     *
     */
    public static final String DOC_YEAR = "docYear";

    /**
     * TODO Auto-generated attribute documentation
     *
     */
    public static final String AUTHOR = "author";

    /**
     * TODO Auto-generated attribute documentation
     *
     */
    public static final String URL = "url";

    /**
     * TODO Auto-generated attribute documentation
     *
     */
    public static final String NAME = "name";

    @Override
    public Page<Document> findAll(Predicate predicate, Pageable pageable) {
        QDocument document = QDocument.document;
        JPQLQuery<Document> query = from(document).where(predicate)
            .offset(pageable.getOffset())
            .limit(pageable.getPageSize())
            .fetchAll();
        return loadPage(query, pageable, document);
    }


    /**
     * TODO Auto-generated method documentation
     *
     * @param globalSearch
     * @param pageable
     * @return Page
     */
    public Page<Document> findAll(GlobalSearch globalSearch, Pageable pageable) {
        QDocument document = QDocument.document;
        JPQLQuery<Document> query = from(document);
        Path<?>[] paths = new Path<?>[] { document.name, document.author, document.docYear, document.url };
        applyGlobalSearch(globalSearch, query, paths);
        AttributeMappingBuilder mapping = buildMapper().map(NAME, document.name).map(AUTHOR, document.author).map(DOC_YEAR, document.docYear).map(URL, document.url);
        applyPagination(pageable, query, mapping);
        applyOrderById(query);
        return loadPage(query, pageable, document);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param ids
     * @param globalSearch
     * @param pageable
     * @return Page
     */
    public Page<Document> findAllByIdsIn(List<Long> ids, GlobalSearch globalSearch, Pageable pageable) {
        QDocument document = QDocument.document;
        JPQLQuery<Document> query = from(document);
        Path<?>[] paths = new Path<?>[] { document.name, document.author, document.docYear, document.url };
        applyGlobalSearch(globalSearch, query, paths);
        // Also, filter by the provided ids
        query.where(document.id.in(ids));
        AttributeMappingBuilder mapping = buildMapper().map(NAME, document.name).map(AUTHOR, document.author).map(DOC_YEAR, document.docYear).map(URL, document.url);
        applyPagination(pageable, query, mapping);
        applyOrderById(query);
        return loadPage(query, pageable, document);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param organisms
     * @param globalSearch
     * @param pageable
     * @return Page
     */
    public Page<Document> findByOrganismsContains(Organism organisms, GlobalSearch globalSearch, Pageable pageable) {
        QDocument document = QDocument.document;
        JPQLQuery<Document> query = from(document);
        Assert.notNull(organisms, "organisms is required");
        query.where(document.organisms.contains(organisms));
        Path<?>[] paths = new Path<?>[] { document.name, document.author, document.docYear, document.url };
        applyGlobalSearch(globalSearch, query, paths);
        AttributeMappingBuilder mapping = buildMapper().map(NAME, document.name).map(AUTHOR, document.author).map(DOC_YEAR, document.docYear).map(URL, document.url);
        applyPagination(pageable, query, mapping);
        applyOrderById(query);
        return loadPage(query, pageable, document);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param specimens
     * @param globalSearch
     * @param pageable
     * @return Page
     */
    public Page<Document> findBySpecimensContains(Specimen specimens, GlobalSearch globalSearch, Pageable pageable) {
        QDocument document = QDocument.document;
        JPQLQuery<Document> query = from(document);
        Assert.notNull(specimens, "specimens is required");
        query.where(document.specimens.contains(specimens));
        Path<?>[] paths = new Path<?>[] { document.name, document.author, document.docYear, document.url };
        applyGlobalSearch(globalSearch, query, paths);
        AttributeMappingBuilder mapping = buildMapper().map(NAME, document.name).map(AUTHOR, document.author).map(DOC_YEAR, document.docYear).map(URL, document.url);
        applyPagination(pageable, query, mapping);
        applyOrderById(query);
        return loadPage(query, pageable, document);
    }
}
